package com.lfz.demo.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lfz.demo.common.target.HoneyLogs;
import com.lfz.demo.common.enums.LogType;
import com.lfz.demo.common.enums.MenuType;
import com.lfz.demo.entity.ChinaPopulation;
import com.lfz.demo.entity.Logs;
import com.lfz.demo.entity.PopulationNews;
import com.lfz.demo.service.IndexService;
import com.lfz.demo.service.PopulationNewsService;
import com.lfz.demo.utils.RedisUtil;
import com.lfz.demo.vo.DataView;
import com.lfz.demo.vo.LogsVo;
import com.lfz.demo.vo.PopulationNewsVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * @author lfz
 * @date 2025/3/5 18:53
 */
@RestController
@RequestMapping("/news")
public class PopulationNewsController {
    private static final Logger logger = LoggerFactory.getLogger(RedisUtil.class);
    // 缓存时间常量（单位：分钟）
    private static final int CACHE_EXPIRE = 60; //缓存过期时间（60分钟）。
    private static final String CACHE_PREFIX = "news:"; //缓存键前缀，避免键冲突。

    @Autowired
    private PopulationNewsService populationNewsService;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 查询所有(分页)
     */
    @GetMapping("/listNews")
    public DataView listNews(PopulationNewsVo populationNewsVo){
        String cacheKey = generateCacheKey(populationNewsVo);

        try {
            // 尝试从缓存获取
            DataView cachedData = (DataView) redisUtil.get(cacheKey);
            if (cachedData != null) {
//                logger.info("命中缓存: {}", cacheKey);
                return cachedData;
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("Redis访问异常，降级到数据库查询", e);
        }

        try {
            // 创建分页对象
            Pageable pageable = PageRequest.of(populationNewsVo.getPage() - 1, populationNewsVo.getLimit());

            // 创建查询条件
            Specification<PopulationNews> spec = (root, query, criteriaBuilder) -> {
                List<Predicate> predicates = new ArrayList<>();
                if (populationNewsVo.getTitle() != null) {
                    predicates.add(criteriaBuilder.like(root.get("title"), "%" + populationNewsVo.getTitle() + "%"));
                }

                // 使得发布时间最新的在最前面
                query.orderBy(criteriaBuilder.desc(root.get("createTime")));

                return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
            };

            // 分页查询
            org.springframework.data.domain.Page<PopulationNews> page = populationNewsService.findByPage(spec, pageable);

            // 返回数据封装
            DataView dataView = new DataView(page.getTotalElements(), page.getContent());

            // 异步缓存结果
            cacheResultAsync(cacheKey, dataView);
            return dataView;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("新闻查询异常", e);
            return new DataView(0L, Collections.emptyList());
        }
    }

    /**
     * 删除
     */
    @HoneyLogs(operation = "删除", type = LogType.DELETE, menu = MenuType.News)
    @PostMapping("/deleteById")
    public DataView deleteById(Integer id){
        DataView dataView = new DataView();
        // 删除前获取新闻信息用于清理缓存
        PopulationNews news = populationNewsService.getById(id);

        boolean b = populationNewsService.removeById(id);
        if (b){
            // 清理相关缓存
            clearRelatedCaches();
            dataView.setCode(200);
            dataView.setMsg("删除成功！");
        }else {
            dataView.setCode(100);
            dataView.setMsg("删除失败！");
        }
        return dataView;
    }

    /**
     * 新增
     */
    @HoneyLogs(operation = "新增", type = LogType.ADD, menu = MenuType.News)
    @PostMapping("/addNews")
    public DataView addNews(PopulationNews populationNews){
        if (populationNews.getId()!= null) {
            // 新增操作，让数据库自动生成 id
            // 确保新增时 id 为 null
            populationNews.setId(null);
        }
        DataView dataView = new DataView();
        boolean b = populationNewsService.save(populationNews);
        if (b){
            // 清理相关缓存
            clearRelatedCaches();
            dataView.setCode(200);
            dataView.setMsg("新增新闻数据成功！");
        } else {
            dataView.setCode(100);
            dataView.setMsg("发生错误，新增新闻数据失败！请联系管理员进行调试！");
        }
        return dataView;
    }

    /**
     * 修改、编辑
     */
    @HoneyLogs(operation = "修改", type = LogType.UPDATE, menu = MenuType.News)
    @PostMapping("/updateNews")
    public DataView updateNews(PopulationNews populationNews){
        DataView dataView = new DataView();
        boolean b = populationNewsService.updateById(populationNews);
        if (b){
            // 清理相关缓存
            clearRelatedCaches();
            dataView.setCode(200);
            dataView.setMsg("编辑新闻数据成功！");
        } else {
            dataView.setCode(100);
            dataView.setMsg("发生错误，编辑新闻数据失败！请联系管理员进行调试！");
        }
        return dataView;
    }

    /**
     * 批量删除数据
     * @param ids
     * @return
     */
    @HoneyLogs(operation = "批量删除", type = LogType.BATCH_DELETE, menu = MenuType.News)
    @PostMapping("/batchDelete")
    public DataView batchDelete(@RequestBody List<Integer> ids) {
        DataView dataView = new DataView();
        try {
            populationNewsService.removeByIds(ids);
            // 清理相关缓存
            clearRelatedCaches();
            dataView.setCode(200);
            dataView.setMsg("批量删除人口数据新闻数据成功");
        } catch (Exception e) {
            e.printStackTrace();
            dataView.setCode(500);
            dataView.setMsg("批量删除失败：" + e.getMessage());
        }
        return dataView;
    }

    /**
     * 生成唯一缓存键
     */
    private String generateCacheKey(PopulationNewsVo vo) {
        return String.format("%slistNews:page-%d_limit-%s_title-%s_content-%s_create_time-%s_pubulishby",
                CACHE_PREFIX,
                vo.getPage(),
                vo.getLimit(),
                org.springframework.util.StringUtils.hasText(vo.getTitle()) ? vo.getTitle() : "all",
                org.springframework.util.StringUtils.hasText(vo.getContent()) ? vo.getContent() : "all",
                vo.getCreateTime() != null ? vo.getCreateTime() : 0,
                org.springframework.util.StringUtils.hasText(vo.getPubulishby()) ? vo.getPubulishby() : "all");
    }

    /**
     * 异步缓存结果
     */
    private void cacheResultAsync(String key, DataView data) {
        new Thread(() -> {
            try {
                redisUtil.set(key, data, CACHE_EXPIRE);
//                logger.info("成功缓存数据 Key: {}", key);
            } catch (Exception e) {
                e.printStackTrace();
//                logger.error("异步缓存设置失败 Key: {}", key, e);
            }
        }).start();
    }

    /**
     * 清理相关缓存
     */
    private void clearRelatedCaches() {
        try {
            redisUtil.deletePattern(CACHE_PREFIX + "*");
            logger.info("成功清理日志相关缓存");
        } catch (Exception e) {
            logger.error("缓存清理失败", e);
        }
    }
}
